<template>
  <div></div>
</template>

<script setup lang="ts">
  import { JSONFile, JSONFilePreset, DataFile } from 'lowdb/node'
  import { Low } from 'lowdb'
  import { resolve } from 'path'
  import lodash from 'lodash'
  import Mock from 'mockjs'
  import crypto from 'crypto'
  import { app } from '@electron/remote'
  function resolvePath(fileName: string) {
    return resolve(process.cwd(), 'db', fileName)
    // return resolve(app.getPath('userData'), fileName)
  }

  type User = {
    id: number
    username: string
    age: number
    userType: string
    sort: number
  }
  type Data = {
    users: User[]
  }
  // 用户数据目录
  const userPath = app.getPath('userData')
  console.log(userPath, 'userPath')
  async function init() {
    const defaultData: Data = { users: [] }
    // 读取或创建 db.json 文件
    const db = await JSONFilePreset(resolvePath('db.json'), defaultData)
    const user = { id: 1, username: 'kunkun', age: 18, userType: 'user', sort: 10 }
    // 写入数据：两部操作
    /*
      db.data.users.push(user)
      await db.write()
    */

    // 一步操作
    await db.update(({ users }) => {
      users.push(user)
    })
  }

  // init()
  // 使用 lodash 扩展 lowdb
  class LowWithLodash<T> extends Low<T> {
    chain: lodash.ExpChain<this['data']> = lodash.chain(this).get('data')
  }

  async function init2() {
    const defaultData: Data = { users: [] }
    const adapter = new JSONFile<Data>(resolvePath('db.json'))
    const db = new LowWithLodash(adapter, defaultData)
    // 读取数据
    await db.read()
    console.log(db.data, 'db.data')
    // 查询数据
    const user = db.chain.get('users').find({ id: 1 }).value()
    const lastUser = db.chain.get('users').last().value()
    const total = db.chain.get('users').size().value()
    const list = db.chain.get('users').sortBy('sort').take(10).value()
    // const list = db.chain.get('users').slice(0, 10).value()

    // 新增数据
    const newUser = Mock.mock({
      id: lastUser.id + 1,
      username: '@cname',
      age: '@integer(18, 30)',
      'userType|1': ['user', 'admin'],
      sort: '@integer(18, 30)'
    })
    db.chain.get('users').push(newUser).value()
    await db.write()

    // 删除数据
    // db.chain.get('users').remove({ id: 3 }).value()
    // db.chain.get('users').remove({ username: 'wuxidxi' }).value()
    // await db.write()

    // 更新数据
    // db.chain.get('users').find({ id: 1 }).assign({ username: '坤坤', userType: 'admin' }).value()
    // await db.write()

    // 添加 list 字段
    // db.chain.set('list', []).value()
    // await db.write()
  }

  // init2()

  // 算法
  const algorithm = 'aes-256-cbc'
  // 秘钥
  const key = crypto.scryptSync('secret', 'salt', 32)
  // 初始化向量
  const iv = Buffer.alloc(16, 6)

  // 加密数据
  function encrypt(data: string) {
    // 创建加密对象
    const cipher = crypto.createCipheriv(algorithm, key, iv)
    // 对数据进行加密
    let encrypted = cipher.update(data, 'utf8')
    // 加密结束
    encrypted = Buffer.concat([encrypted, cipher.final()])
    // 生成 16 进制密文
    let result = encrypted.toString('hex')
    return result
  }

  // 解密
  function decrypt(text: string) {
    // 创建解密对象
    const decipher = crypto.createDecipheriv(algorithm, key, iv)
    // 进行解密
    let decrypted = decipher.update(text, 'hex')
    // 解密结束
    decrypted = Buffer.concat([decrypted, decipher.final()])
    let result = decrypted.toString()
    return result
  }

  async function init3() {
    const defaultData: Data = { users: [] }
    const adapter = new DataFile<Data>(resolvePath('file.json'), {
      parse: (data) => {
        return JSON.parse(decrypt(data))
      },
      stringify: (data) => {
        return encrypt(JSON.stringify(data))
      }
    })
    const db = new Low(adapter, defaultData)

    const user = { id: 1, username: 'kunkun', age: 18, userType: 'user', sort: 10 }

    await db.read()
    console.log(db.data, 'db.data')

    await db.update(({ users }) => {
      users.push(user)
    })
  }

  init3()
</script>

<style scoped></style>
